<template>
  <div
    class="pull-refresh"
    @touchstart="onStart"
    @touchmove="onMove"
    @touchend="onEnd"
    @touchcancel="onEnd"
  >
    <div class="wrapper"
      :style="wrapperStyle"
    >
      <div class="status">{{ status }}</div>
      <ul
        class="list"
      >
        <li v-for="d in list" :key="d">{{ d }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
const ajax=()=>{
  return new Promise(resolve=>{
    setTimeout(()=>{
      resolve(new Array(10).fill(0).map(()=>Math.random()));
    },Math.random()*2000)
  })
}
//顶部文字"下拉加载"默认是隐藏的
//往下拖动时,列表下移,顶部文字跟随着逐渐显示出来
//如果下移距离超过阈值(一个距离)/触发距离,文字就变成了"释放加载",此时放开手指,文字变成"正在加载",请求数据接口,接口请求成功会后,文字恢复默认,并且将顶部隐藏,列表复位
  export default {
    data(){
      return {
        loading: false,
        list:[],
        //触摸点Y方向位置坐标
        startY: 0,
        endY: 0,
        y: 0,//下拉的距离
        transitionDuration:'0s'
      }
    },
    methods:{
      getList(){
        this.loading=true
        return ajax().then(data=>{
          this.list =[...this.list,...data]
          this.loading = false
        });
      },
      ease(n,limit){
        if(n > limit){
          if(n< limit*2){
            n = limit + (n-limit) / 2
          } else {
            n = limit * 1.5 + (n-limit*2) / 4
          }
        }
        return n;
      },
      onStart(e){
        if(this.loading || window.pageYOffset > 0) return;
        this.startY= e.touches[0].clientY
      },
      onMove(e){
        this.transitionDuration='0s'
        //先判断是不是在页面未发生滚动时
        if(this.loading || window.pageYOffset > 0) return
        //如果已经发生拖动,禁用默认的页面滚动
        if(this.y>0) e.preventDefault();
        // const limit= n=>Math.max(Math.min(100,n),0)
        this.endY= e.touches[0].clientY
        this.y=this.ease(Math.max(this.endY-this.startY,0),50)
      },
      onEnd(){
        this.transitionDuration='0.3s'
        if(this.y > 50){
          this.y=50
          this.getList().then(()=>{
            this.y=0
          })
        }else {
          this.y=0
        }
      }
    },
    mounted(){
      this.getList()
    },
    computed:{
      status(){
        if(this.loading)
          return '正在加载';
        if(this.y>50)
          return '释放加载';
        return '下拉加载'
      },
      wrapperStyle(){
        return {
          'transform':`translateY(${this.y}px)`,
          'transition':this.transitionDuration
        }
      }
    }
  }
</script>

<style lang="sass">
.pull-refresh
  text-align: center
  overflow: hidden
  .wrapper
   position: relative
  .status
    width: 100%
    position: absolute
    top: -50px
    line-height: 50px
  .list
    max-width: 500px
    margin: 0 auto
    li
      line-height: 50px
      &:nth-child(odd)
        background: #f0c0f0
      &:nth-child(even)
        background: #f55
</style>
